using System;
using System.Collections;
using System.Diagnostics;
using System.Text;
using ActiproSoftware.SyntaxEditor.Addons.Simple.Ast;

namespace ActiproSoftware.SyntaxEditor.Addons.Simple.Ast {

	/// <summary>
	/// Represents a binary expression.
	/// </summary>
	public class BinaryExpression : ActiproSoftware.SyntaxEditor.Addons.Simple.Ast.Expression {

		private OperatorType	operatorType;

		/// <summary>
		/// Gets the context ID for the left expression affected by the binary operator.
		/// </summary>
		public const byte LeftExpressionContextID = ActiproSoftware.SyntaxEditor.Addons.Simple.Ast.Expression.ExpressionContextIDBase;

		/// <summary>
		/// Gets the context ID for the right expression affected by the binary operator.
		/// </summary>
		public const byte RightExpressionContextID = ActiproSoftware.SyntaxEditor.Addons.Simple.Ast.Expression.ExpressionContextIDBase + 1;

		/// <summary>
		/// Gets the minimum context ID that should be used in your code for AST nodes inheriting this class.
		/// </summary>
		/// <remarks>
		/// Base all your context ID constants off of this value.
		/// </remarks>
		protected const byte BinaryExpressionContextIDBase = ActiproSoftware.SyntaxEditor.Addons.Simple.Ast.Expression.ExpressionContextIDBase + 2;

		/////////////////////////////////////////////////////////////////////////////////////////////////////
		// OBJECT
		/////////////////////////////////////////////////////////////////////////////////////////////////////

		/// <summary>
		/// Initializes a new instance of the <c>BinaryExpression</c> class.
		/// </summary>
		/// <param name="operatorType">An <see cref="OperatorType"/> indicating the binary operator type.</param>
		/// <param name="leftExpression">The left <see cref="Expression"/> affected by the unary operator.</param>
		/// <param name="rightExpression">The right <see cref="Expression"/> affected by the unary operator.</param>
		/// <param name="textRange">The <see cref="TextRange"/> of the expression.</param>
		public BinaryExpression(OperatorType operatorType, Expression leftExpression, Expression rightExpression, TextRange textRange) : this(textRange) {
			// Initialize parameters
			this.operatorType		= operatorType;
			this.LeftExpression		= leftExpression;
			this.RightExpression	= rightExpression;
		}

		/// <summary>
		/// Initializes a new instance of the <c>BinaryExpression</c> class. 
		/// </summary>
		public BinaryExpression() {}

		/// <summary>
		/// Initializes a new instance of the <c>BinaryExpression</c> class. 
		/// </summary>
		/// <param name="textRange">The <see cref="TextRange"/> of the AST node.</param>
		public BinaryExpression(TextRange textRange) : base(textRange) {}

		/////////////////////////////////////////////////////////////////////////////////////////////////////
		// PUBLIC PROCEDURES
		/////////////////////////////////////////////////////////////////////////////////////////////////////

		/// <summary>
		/// Accepts the specified visitor for visiting this node.
		/// </summary>
		/// <param name="visitor">The visitor to accept.</param>
		/// <remarks>This method is part of the visitor design pattern implementation.</remarks>
		protected override void AcceptCore(AstVisitor visitor) {
			if (visitor.OnVisiting(this)) {
				// Visit children
				if (this.ChildNodeCount > 0)
					this.AcceptChildren(visitor, this.ChildNodes);
			}
			visitor.OnVisited(this);
		}
		
		/// <summary>
		/// Gets the image index that is applicable for displaying this node in a user interface control.
		/// </summary>
		/// <value>The image index that is applicable for displaying this node in a user interface control.</value>
		public override int ImageIndex {
			get {
				return (System.Int32)ActiproSoftware.Products.SyntaxEditor.IconResource.Operator;
			}
		}

		/// <summary>
		/// Gets the <see cref="SimpleNodeType"/> that identifies the type of node.
		/// </summary>
		/// <value>The <see cref="SimpleNodeType"/> that identifies the type of node.</value>
		public override SimpleNodeType NodeType { 
			get {
				return SimpleNodeType.BinaryExpression;
			}
		}

		/// <summary>
		/// Gets or sets the left expression affected by the binary operator.
		/// </summary>
		/// <value>The left expression affected by the binary operator.</value>
		public Expression LeftExpression {
			get {
				return this.GetChildNode(BinaryExpression.LeftExpressionContextID) as Expression;
			}
			set {
				this.ChildNodes.Replace(value, BinaryExpression.LeftExpressionContextID);
			}
		}

		/// <summary>
		/// Gets or sets the right expression affected by the binary operator.
		/// </summary>
		/// <value>The right expression affected by the binary operator.</value>
		public Expression RightExpression {
			get {
				return this.GetChildNode(BinaryExpression.RightExpressionContextID) as Expression;
			}
			set {
				this.ChildNodes.Replace(value, BinaryExpression.RightExpressionContextID);
			}
		}

		/// <summary>
		/// Gets or sets an operator type indicating the binary operator type.
		/// </summary>
		/// <value>An operator type indicating the binary operator type.</value>
		public OperatorType OperatorType {
			get {
				return operatorType;
			}
			set {
				operatorType = value;
			}
		}

		/// <summary>
		/// Gets text representing the node that can be used for display, such as in a document outline.
		/// </summary>
		/// <value>Text representing the node that can be used for display, such as in a document outline.</value>
		public override string DisplayText {
			get {
				return "Binary Expression " + this.OperatorType;
			}
		}

	}

}
